using System;
using System.Collections.Generic;
using System.Linq;
using Db4objects.Db4o.Linq;
using SharedObjects;

namespace TheGameDatabaseTool
{
	public partial class DatabaseMainScript
	{
		private Account CreateNewAgentAccount(ulong accountId, string login, string password, string displayName, Corporation corp, NetworkAddress nwa, bool isAdmin)
		{
			if(corp == null)
				throw new ArgumentException("Corp");
			Account account = GetEntity<Account>(accountId);
			account.AccountStatus = AccountStatus.Active;
			account.HasLoggedIn = false;
			account.IsAdmin = isAdmin;
			account.IsDeleted = false;
			account.Login = login;
			account.Password = password;
			account.RegistrationDateReal = DateTime.Now;
			account.RegistrationDateWorld = _worldTime;

			ulong agentId = account.Agent != null ? account.Agent.Id : Extension.ToLong(Guid.NewGuid());

			Agent agent = GetEntity<Agent>(agentId);
			agent.BankAccounts = agent.BankAccounts ?? new List<BankAccount>();
			agent.ComputerSystemAccounts = agent.ComputerSystemAccounts ?? new List<ComputerSystemAccount>();
			agent.ComputerSystemIds = agent.ComputerSystemIds ?? new List<ulong>();
			agent.Corporation = corp;
			agent.DisplayName = displayName;
			agent.EmailAccounts = agent.EmailAccounts ?? new List<EmailAccount>();
			agent.Gateway = agent.Gateway ?? CreateDefaultGateway(displayName, corp, nwa);
			agent.IsDeleted = false;
			agent.SavedConnections = agent.SavedConnections ?? new List<SavedConnection>();
			agent.UserPrograms = agent.UserPrograms ?? new List<UserProgram>();
			agent.OwnedHardware = agent.OwnedHardware ?? new List<IHardware>();

			account.Agent = agent;
			return account;
		}

		private Gateway CreateDefaultGateway(string displayName, Corporation corp, NetworkAddress nwa)
		{
			Guid rootId = Guid.NewGuid();

			SystemDirectory systemDirectory = GetEntity<SystemDirectory>(Extension.ToLong(rootId));
			systemDirectory.Id = Extension.ToLong(rootId);
			systemDirectory.IsDeleted = false;
			systemDirectory.Name = string.Format("{0}'s Gateway Root", displayName);

			Guid csId = Guid.NewGuid();
			ComputerSystem cs = GetEntity<ComputerSystem>(Extension.ToLong(csId));
			cs.Accounts = new List<ComputerSystemAccount>();
			cs.AlwaysInvisible = true;
			cs.ComputerSystemFeatures = new List<ComputerSystemFeature>();
			cs.ComputerSystemLogs = new List<ComputerSystemLog>();
			cs.Corporation = corp;
			cs.DifficultyLevel = 6;
			cs.Id = Extension.ToLong(csId);
			cs.IsDeleted = false;
			cs.IsGatewayCentral = false;
			cs.MaintenanceInterval = 0;
			cs.MapX = 0;
			cs.MapY = 0;
			cs.Name = string.Format("{0}'s Gateway", displayName);
			cs.NetworkAddress = nwa;
			cs.RootDirectory = systemDirectory;
			cs.SecuritySystem = new List<SecuritySystem>();
			cs.TrustedConnectionOnly = true;

			Cpu defaultCPU = (from Cpu cpu in Db where cpu.IsDefault select cpu).FirstOrDefault();
			if (defaultCPU == null)
				throw new Exception("No default cpu defined.");

			NetworkAdapter defaultNic = (from NetworkAdapter n in Db where n.IsDefault select n).FirstOrDefault();
			if (defaultNic == null)
				throw new Exception("No default nic defined.");

			MemoryType defaultMemory = (from MemoryType m in Db where m.IsDefault select m).FirstOrDefault();
			if (defaultMemory == null)
				throw new Exception("No default memory defined.");

			GatewayBlueprint defaultGatewayBlueprint = (from GatewayBlueprint gwp in Db where gwp.IsDefault select gwp).FirstOrDefault();
			if (defaultGatewayBlueprint == null)
				throw new Exception("No default blueprint defined.");

			if (defaultGatewayBlueprint.MaxCpuSpeed < defaultCPU.Modifier)
				throw new Exception("Invalid default-cpu speed or maxcpuspeed on blueprint.");
			if (defaultGatewayBlueprint.MaxMemorySize < defaultMemory.Modifier)
				throw new Exception("Invalid default-memory capacity or maxmemorysize on blueprint.");
			if (defaultGatewayBlueprint.MaxBandwidth < defaultNic.Modifier)
				throw new Exception("Invalid default-nic speed or maxbandwidth on blueprint.");

			Guid gwId = Guid.NewGuid();
			Gateway gateway = GetEntity<Gateway>(Extension.ToLong(gwId));
			{
				gateway.ComputerSystem = cs;
				gateway.InstalledCpus = new List<Cpu> {defaultCPU};
				gateway.GatewayBlueprint = defaultGatewayBlueprint;
				gateway.Id = Extension.ToLong(gwId);
				gateway.InstalledMemory = new List<MemoryType> {defaultMemory};
				gateway.InstalledNics = new List<NetworkAdapter> {defaultNic};
			}

			return gateway;
		}
	}
}